#include "fbtransferthread.h"
#include "filebrowser.h"
#include "NetworkCommonFunction.h"

#include <QFile>
#include <QDebug>
#include <boost/scoped_array.hpp>

struct SocketCloser
{
	SocketCloser(int socket):
			m_Socket(socket)
	{
	}
	~SocketCloser()
	{
		closesocket(m_Socket);
	}

private:
	int m_Socket;
};

FBTransferThread::FBTransferThread(int socket):
		m_Socket(socket)
{
}

void FBTransferThread::run()
{
	SocketCloser socketCloser(m_Socket);
	int clientId;
	if(!getFourByte(m_Socket, clientId))
	{
		qDebug()<<"Get file browser client id error";
//		emit errorHappend(transferId, WSAGetLastError());
		return;
	}

	FileBrowser* fileBrowser = FileBrowserCreator::instance()->createFileBrowser(clientId);
	connect(this, SIGNAL(transferredSizeChangged(int,long long)),
			fileBrowser, SLOT(onTransferSizeChanged(int,long long)));
	connect(this, SIGNAL(transferComplete(int)),
			fileBrowser, SLOT(onTransferComplete(int)));
	connect(this, SIGNAL(errorHappend(int,int)),
			fileBrowser, SLOT(onTransferErrorHappend(int,int)));

	int transferId;
	if(!getFourByte(m_Socket, transferId))
	{
		qDebug()<<"Get file browser transfer id error";
//		emit errorHappend(transferId, WSAGetLastError());
		return;
	}

	int saveFileNameLen;
	if(!getFourByte(m_Socket, saveFileNameLen))
	{
		qDebug()<<"Get file name len error";
		emit errorHappend(transferId, WSAGetLastError());
		return;
	}

	char* saveFileNameBuffer = new char[saveFileNameLen + 1];
	boost::scoped_array<char> saveFileNameBufferContainer(saveFileNameBuffer);
	saveFileNameBuffer[saveFileNameLen] = 0;

	if(!receiveData(m_Socket, saveFileNameBuffer, saveFileNameLen))
	{
		qDebug()<<"Get file name error";
		emit errorHappend(transferId, WSAGetLastError());
		return;
	}

	emit transferStart(transferId);

	const int bufferSize  = 50 * 1024;
	char* buffer = new char[bufferSize];
	boost::scoped_array<char> bufferContainer(buffer);

	QString saveFileName = QString::fromUtf8(saveFileNameBuffer, saveFileNameLen);
	QFile saveFile(saveFileName);
	if(!saveFile.open(QFile::WriteOnly))
	{
		qDebug()<<"Open file to write error";
		emit errorHappend(transferId, 0x999);
		return;
	}

	long long recvedSize = 0;
	while(true)
	{
		long long thisRecvedSize = ::recv(m_Socket, buffer, bufferSize, 0);
		if(thisRecvedSize == SOCKET_ERROR)
		{
			qDebug()<<"File transfer "<<transferId<<" recv error";
			emit errorHappend(transferId, WSAGetLastError());
			return;
		}
		else if(thisRecvedSize == 0)
		{
			qDebug()<<"File transfer "<<transferId<<" complete";
			emit transferComplete(transferId);
			return;
		}
		long long writeSize = saveFile.write(buffer, thisRecvedSize);
		if(writeSize == -1)
		{
			qDebug()<<"Write to file error";
			emit errorHappend(transferId, 0x998);
			return;
		}
		recvedSize += thisRecvedSize;
		qDebug()<<"Received size "<<recvedSize;
		emit transferredSizeChangged(transferId, recvedSize);
	}
}
